package com.bw.util;



import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.github.xiaoymin.knife4j.core.io.ResourceUtil;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.trtc.v20190722.TrtcClient;
import com.tencentcloudapi.trtc.v20190722.models.*;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.DeleteMediaRequest;
import com.tencentcloudapi.vod.v20180717.models.DeleteMediaResponse;
import com.tencentcloudapi.vod.v20180717.models.DescribeMediaInfosResponse;
import com.tencentyun.TLSSigAPIv2;
import org.springframework.util.ResourceUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;
import java.util.logging.Logger;

/**
 * @Author: FanYangJie
 * @BelongsProject: Y2102A_day0910
 * @BelongsPackage: com.bw.pxx.live.utils
 * @Date: 2023/9/18 11:48
 * @Description: TODO
 */
public class TxLiveUtils {
    public static void main(String[] args) {
        System.out.println(getSafeUrl("txrtmp", "11212122", 1469762325L));
    }

    private static final char[] DIGITS_LOWER =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /*
     * KEY+ streamName + txTime
     */
    private static String getSafeUrl(String key, String streamName, long txTime) {
        String input = new StringBuilder().
                append(key).
                append(streamName).
                append(Long.toHexString(txTime).toUpperCase()).toString();

        String txSecret = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            txSecret  = byteArrayToHexString(
                    messageDigest.digest(input.getBytes("UTF-8")));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return txSecret == null ? "" :
                new StringBuilder().
                        append("txSecret=").
                        append(txSecret).
                        append("&").
                        append("txTime=").
                        append(Long.toHexString(txTime).toUpperCase()).
                        toString();
    }

    private static String byteArrayToHexString(byte[] data) {
        char[] out = new char[data.length << 1];

        for (int i = 0, j = 0; i < data.length; i++) {
            out[j++] = DIGITS_LOWER[(0xF0 & data[i]) >>> 4];
            out[j++] = DIGITS_LOWER[0x0F & data[i]];
        }
        return new String(out);
    }

    /**
     * @description 生成推流地址
     * @author 军哥
     * @date 2022/8/26 18:31
     * @version 1.0
     */

    public static String makePushUrl(String streamName, Integer minutes) {

        Long lTime = System.currentTimeMillis()/1000L + 60*minutes;

        // webrtc://live.shenmazong.com/live/36301?txSecret=134321418f9cfc673c9bfc141c0ecf03&txTime=6309C85A
        String safeUrl = getSafeUrl("58a6b8cd7e90ac348a9768387d82222f", streamName, lTime);
        String url = "webrtc://live.shenmazong.com/live/" + streamName + "?" + safeUrl;

        return url;
    }

    public static String makePushUrl(String streamName, Date closeTime) {
        Long lTime = closeTime.getTime() / 1000;

        // webrtc://live.shenmazong.com/live/36301?txSecret=134321418f9cfc673c9bfc141c0ecf03&txTime=6309C85A
        String safeUrl = getSafeUrl("58a6b8cd7e90ac348a9768387d82222f", streamName, lTime);
        String url = "webrtc://live.shenmazong.com/live/" + streamName + "?" + safeUrl;

        return url;
    }

    /**
     * @description 获取直播地址
     * @author 军哥
     * @date 2022/8/27 14:22
     * @version 1.0
     */
    public static String makePlayUrl(String roomNo) {
        // http://play.shenmazong.com/live/32301.m3u8
        return "http://play.shenmazong.com/live/" + roomNo + ".m3u8";
    }

    /**
     * @deprecated: TODD 回调秘钥
     * @Author: FAnYangJie〔^.べ〕γ
     * @Date: 2023/11/15 11:49
     */
    public  static String getResultSign(String key, String body) throws Exception {
        Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        hmacSHA256.init(secret_key);
        return Base64.getEncoder().encodeToString(hmacSHA256.doFinal(body.getBytes()));
    }

    /**
     * @deprecated: TODD 开启腾讯云直播录制
     * @Author: FAnYangJie〔^.べ〕γ
     * @Date: 2023/11/15 12:00
     */
    public static String openCloudRecording(String userId, String roomId){
        try {
            //创建文件对象
            Properties properties = new Properties();

            //家财文件获取数据,  文件带后缀
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream
                    ("application.properties"));
            //根据key获取value
            String secretid = properties.getProperty("secretid");
            String secretkey = properties.getProperty("secretkey");
            String expiretime = properties.getProperty("expiretime");
            String sdkappid = properties.getProperty("sdkappid");
            String key = properties.getProperty("key");
            Credential credential = new Credential(secretid, secretkey);
            //实例化一个http请求 可选地 没有特殊请求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("trtc.tencentcloudapi.com");
            //实例化一个client选项,可选的,没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            //是李华邀请求产品的clent对象,clientFile是可选择的;
            TrtcClient client = new TrtcClient(credential, "ap-beijing", clientProfile);
            //实例化一个请求对象 每个接口都会对应一个request对象
            CreateCloudRecordingRequest request = new CreateCloudRecordingRequest();
            request.setSdkAppId(Long.valueOf(sdkappid));//和直播的appID相同
            request.setRoomId(roomId);
            request.setRoomIdType(1L);
            /**
             *  录制机器人用于进入TRTC房间拉流的[UserId](https://cloud.tencent.com/document/product/647/46351#userid)，
             *  注意这个UserId不能与其他TRTC房间内的主播或者其他录制任务等已经使用的UserId重复，建议可以把房间ID作为userId的标识的一部分，
             *  即录制机器人进入房间的userid应保证独立且唯一
             */
            request.setUserId(userId);

            TLSSigAPIv2 api = new TLSSigAPIv2(Long.valueOf(sdkappid), key);
            String userSig = api.genUserSig(userId, Long.valueOf(expiretime));
            request.setUserSig(userSig);// 录制机器人用于进入TRTC房间拉流的用户签名，当前 UserId 对应的验证签名，相当于登录密码
            //单流录制
            RecordParams recordParams = new RecordParams();
            recordParams.setMaxIdleTime(30L);//30喵内找不到主播停止录制
            recordParams.setStreamType(0L);//0 录制音频加视频流
            recordParams.setRecordMode(1L);// 单流录制，分别录制房间的订阅UserId的音频和视频，将录制文件上传至云存储； 2：混流录制，将房间内订阅UserId的音视频混录成一个音视频文件，将录制文件上传至云存储；
            recordParams.setOutputFormat(0L);//0：(默认)输出文件为hls格式。1：输出文件格式为hls+mp4。2：输出文件格式为hls+aac

            StorageParams storageParams = new StorageParams();
            CloudVod cloudVod = new CloudVod();
            TencentVod tencentVod = new TencentVod();
            cloudVod.setTencentVod(tencentVod);//腾讯云直播录制
            storageParams.setCloudVod(cloudVod);//必填】腾讯云云点播的账号信息，目前仅支持存储至腾讯云点播VOD。
            request.setRecordParams(recordParams);//云端录制控制参数
            request.setStorageParams(storageParams);// 云端录制文件上传到云存储的参数(目前只支持使用腾讯云点播作为存储)

            // 返回的resp是一个CreateCloudRecordingResponse的实例，与请求对象对应
            CreateCloudRecordingResponse resp=client.CreateCloudRecording(request);
            //输出json法师的字符串汇报
            String s= JSON.toJSONString(resp);
            return s;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @deprecated: TODD 关闭腾讯云直播
     * @Author: FAnYangJie〔^.べ〕γ
     * @Date: 2023/11/15 15:45
     */
    public static String closeDeleteCloudRecording(String taskId){
        try {
            if (taskId!=null){
                taskId= taskId.replaceAll(" ", "+");
            }
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            //创建文件对象
            Properties properties = new Properties();
            //加载文件加载数据
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream
                    ("bootstrap.yml"));
            //根据key来获取value
            String SecretId = properties.getProperty("secretid");
            String SecretKey = properties.getProperty("secretkey");
            String sdkAppId = properties.getProperty("sdkappid");
            Credential cred = new Credential(SecretId, SecretKey);
            //实例化一个http请求,可选的,没有特殊请求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("trtc.tencentcloudapi.com");
            //实例化一个http选项 可选的,每一要求可以跳过

            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            //实例化要请求状态的数据.可选
            TrtcClient client = new TrtcClient(cred, "ap-beijing", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DeleteCloudRecordingRequest req = new DeleteCloudRecordingRequest();
            req.setSdkAppId(Long.valueOf(sdkAppId)); // SdkAppId – TRTC的SDKAppId，和录制的房间所对应的SDKAppId相同
            req.setTaskId(taskId); // TaskId – 录制任务的唯一Id，在启动录制成功后会返回
            // 返回的resp是一个DeleteCloudRecordingResponse的实例，与请求对象对应
            DeleteCloudRecordingResponse resp = client.DeleteCloudRecording(req);
            // 输出json格式的字符串回包
            String s = JSON.toJSONString(resp);
            return s;
        } catch (IOException | TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @deprecated: TODD 查询出音视频集合 并下载 在云点播上将视频删除
     * @Author: FAnYangJie〔^.べ〕γ
     * @Date: 2023/11/15 18:39
     */
    public static   void  downloadVideo(String [] fileIds)throws Exception{
        try {
            //创建文件对象
            Properties properties = new Properties();
            //加载文件获取数据
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream
                    ("bootstrap.yml"));
            //根据key获取value
            String secretid = properties.getProperty("secretid");
            String secretkey = properties.getProperty("secretkey");
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(secretid, secretkey);
            //实例化一个http对象 可选的 没有符合压球的可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("vod.tencentcloudept.com");
            //实例化一个client对象,可选的
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            VodClient client = new VodClient(cred, "ap-beijing", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DescribeCallDetailInfoRequest resp = new DescribeCallDetailInfoRequest();
            //输出json格式的字符串值
            // Logger.info(DescribeCallDetailInfoResponse.toJsonString(resp));
            String json = DescribeMediaInfosResponse.toJsonString(resp);
            JSONObject jsonObject= (JSONObject) JSON.parse(json);
            JSONArray jsonArray = jsonObject.getJSONArray("MediaInfoSet");
            for (int i = 0; i < jsonArray.size(); i++) {{
                JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                //点播平台的唯一Id
                String fileeId = jsonObject1.getString("FileId");
                //基础信息
                String basicInfo = jsonObject1.getString("BasicInfo");
                JSONObject jsonObject2=JSON.parseObject(basicInfo);
                //文件地址
                String mediaUrl = jsonObject2.getString("MediaUrl");
                //下载音视频(返回本地下载地址)
                String dowPath = downloadImage(mediaUrl);
                //将下载的音视频列出来,进行下载到服务器上 并更新数据
                //业务逻辑处理
                delvideo(fileeId);
                System.out.println(dowPath);
            }}

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @deprecated: TODD 蒋视频下载到本地
     * @Author: FAnYangJie〔^.べ〕γ
     * @Date: 2023/11/15 19:34
     */
    public static String downloadImage(String fileUrl) {
        long l=0L;
        String path=null;
        String staticAndMksDir=null;
        if (fileUrl!=null){
            //下载时文件名称
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("."));
            try {
                String dateStr = new SimpleDateFormat("yyyMMdd").format(new Date());
                String uuidName = UUID.randomUUID().toString();
                path = "resources/images/" + dateStr + "\\" + uuidName + fileName;
                Paths.get(ResourceUtils.getURL("classpath:").getPath(),"resources","images",dateStr).toFile().toString();
                HttpUtil.downloadFile(fileUrl, staticAndMksDir + File.separator + uuidName + fileName);

            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }finally {
                System.out.println("下载成功");
            }
        }
        System.out.println(System.currentTimeMillis()-l);
        return path;
    }

    /**
     * @deprecated: TODD 删除音视频
     * @Author: FAnYangJie〔^.べ〕γ
     * @Date: 2023/11/15 20:24
     */
    public static void  delvideo(String fileId)throws Exception{
        try {
            //创建文件对象
            Properties properties = new Properties();
            //加载文件获取数据 文件带后缀
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream
                    ("bootstrap.yml"));
            //根据key获取value
            String secretid = properties.getProperty("secretid");
            String secretkey = properties.getProperty("secretkey");
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential credential = new Credential(secretid, secretkey);
            //s实例化http请求 可选的 没有特别需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("vof.tencentcloudapi.com");
            //创建一个client对象, 可选的
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            VodClient client = new VodClient(credential , "", clientProfile);
            //实例化对象
            DeleteMediaRequest req = new DeleteMediaRequest();
            req.setFileId(fileId);
            //返货夜歌deletemedial示例
            DeleteMediaResponse resp = client.DeleteMedia(req);
            //输出就送格式的字符串回报
            //输出son格式的字符串回报
            System.out.println("删除音视频成功");
            System.out.println("删除音视频"+DeleteMediaResponse.toJsonString(resp));
        }catch (TencentCloudSDKException e){
            System.out.println(e.toString());
        }
    }
}
